﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mighty.Common;
using System.Collections;

namespace Mighty.Brain
{
    public class CowBrain : BasicBrain
    {
        public override Betting BettingTicEvent()
        {
            int[] cardCnt = new int[5];
            int[] scoreCardCnt = new int[5];

            foreach (HandedCard hc in gameInfo.myCards)
            {

                if (hc.shape == Shape.Clover) cardCnt[0]++;
                if (hc.shape == Shape.Diamond) cardCnt[1]++;
                if (hc.shape == Shape.Spade) cardCnt[2]++;
                if (hc.shape == Shape.Heart) cardCnt[3]++;
                if (hc.shape == Shape.Joker) cardCnt[4]++;

                if (hc.shape == Shape.Clover && hc.number > 9) scoreCardCnt[0]++;
                if (hc.shape == Shape.Diamond && hc.number > 9) scoreCardCnt[1]++;
                if (hc.shape == Shape.Spade && hc.number > 9) scoreCardCnt[2]++;
                if (hc.shape == Shape.Heart && hc.number > 9) scoreCardCnt[3]++;
            }

            int maxnumber = 0;
            int scoreMaxNumber = 0;
            int index = -1;


            if (cardCnt[0] > cardCnt[1])
            {
                maxnumber = cardCnt[0];
                index = 0;
            }
            else
            {
                maxnumber = cardCnt[1];
                index = 1;
            }

            for (int i = 2; i < 4; i++)
            {
                if (cardCnt[i] > maxnumber)
                {
                    maxnumber = cardCnt[i];
                    scoreMaxNumber = scoreCardCnt[i];
                    index = i;
                }
            }

            Giruda mostShape = new Giruda();
            switch (index)
            {
                case 0: mostShape = Giruda.Clover; break;
                case 1: mostShape = Giruda.Diamond; break;
                case 2: mostShape = Giruda.Spade; break;
                case 3: mostShape = Giruda.Heart; break;
            }

            /*
            if (index == 0) mostShape = Giruda.Clover;
            else if (index == 1) mostShape = Giruda.Diamond;
            else if (index == 2) mostShape = Giruda.Spade;
            else if (index == 3) mostShape = Giruda.Heart;
            */

            Betting betting = new Betting();
            betting.giruda = mostShape;

            if (maxnumber > 3 && scoreMaxNumber > 0)
            {
                if (gameInfo.betting.limit > 0)
                {
                    Betting previousBetting = (Betting)gameInfo.bettingHistory[gameInfo.bettingHistory.Count - 1];
                    if (previousBetting.limit < 15)
                    {
                        betting.isPass = false;
                        betting.limit = previousBetting.limit + 1;
                    }
                    else
                    {
                        betting.isPass = true;
                    }
                }
                else
                {
                    betting.isPass = false;
                    betting.limit = 13;
                }
            }
            else if (maxnumber > 5 && scoreMaxNumber > 1)
            {
                Betting previousBetting = (Betting)gameInfo.bettingHistory[gameInfo.bettingHistory.Count - 1];
                if (previousBetting.limit < 18)
                {
                    betting.isPass = false;
                    betting.limit = previousBetting.limit + 1;
                }
                else
                {
                    betting.isPass = true;
                }
            }
            else
            {
                betting.isPass = true;
            }

            return betting;
        }

        public override HandedCard[] ChoiceCardEvent()
        {

            List<HandedCard> noCard = new List<HandedCard>();

            for (int i = 0; i < 13; i++)
            {
                if (gameInfo.myCards[i].shape != (Shape)gameInfo.betting.giruda && gameInfo.myCards[i].shape != Shape.Joker)
                    noCard.Add(gameInfo.myCards[i]);
            }

            HandedCard temp;

            for (int i = 0; i < noCard.Count - 1; i++)
            {
                for (int j = i + 1; j < noCard.Count; j++)
                {
                    if ((noCard[i]).number > (noCard[j]).number)
                    {
                        temp = noCard[i];
                        noCard[i] = noCard[j];
                        noCard[j] = temp;
                    }
                }
            }
            int count = 0;
            while (count > 2)
            {
                for (int j = 1; j < gameInfo.myCards.Length; j++)
                {
                    if (noCard[j].cmdRemove == false)
                        if ((noCard[j]).number == gameInfo.myCards[j].number && (noCard[j]).shape == gameInfo.myCards[j].shape)
                        {

                            gameInfo.myCards[j].cmdRemove = true;
                            count++;
                        }
                }
            }


            return gameInfo.myCards;
        }


        public override FriendPlayer ChoiceFriendEvent()
        {
            FriendPlayer friendPlayer = new FriendPlayer();
            int mig = 0;
            int jok = 0;

            foreach (HandedCard hc in gameInfo.myCards)
            {
                if (hc == gameInfo.mighty)
                    mig = 1;

                if (hc.shape == Shape.Joker)
                    jok = 1;
            }

            if (mig == 1)
            {
                if (jok == 1)
                    gameInfo.friend.howToSelect = FriendPlayer.HowToSelect.firstwin;
                else
                {
                    Card card = new Card();
                    card.shape = Shape.Joker;

                    gameInfo.friend.howToSelect = FriendPlayer.HowToSelect.card;
                    gameInfo.friend.cardCondition = card;
                }
            }

            else if (mig == 0)
            {
                gameInfo.friend.howToSelect = FriendPlayer.HowToSelect.card;
                gameInfo.friend.cardCondition = gameInfo.mighty;
            }

            return gameInfo.friend;

        }

        public override HandedCard RoundTicEvent()
        {
            int stackmaxnumber;

            List<HandedCard> possibleCards = new List<HandedCard>();
            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible) possibleCards.Add((HandedCard)card.Clone());
            }

            ArrayList round_Cards = new ArrayList();

            Round r = gameInfo.roundHistory[gameInfo.roundIdx];

            int scoreCardCnt = 0;
            for (int i = 0; i < 5; i++)
            {
                RoundCard rc = r.cardStack[i];
                if (rc == null) break;

                if (rc.number > 9) scoreCardCnt++;

                //카드를 나온 카드 저장소에 넣는다
                round_Cards.Add(rc);

            }

            HandedCard joker = null;
            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible)
                {
                    if (card.shape == Shape.Joker) joker = card;
                    possibleCards.Add((HandedCard)card.Clone());
                }
            }



            if (gameInfo.roundCardIdx > 1)
            {
                if (r.cardStack[0].shape == Shape.Joker || r.cardStack[1].shape == Shape.Joker)
                    return (HandedCard)possibleCards[0];

                else if (scoreCardCnt > 1)
                {
                    if (joker != null) return joker;
                }

                stackmaxnumber = 0;

                for (int i = 0; i < possibleCards.Count - 1; i++)
                {
                    for (int j = i + 1; j < possibleCards.Count; j++)
                    {

                        int temp;
                        if (possibleCards[i].number > possibleCards[j].number)
                        {
                            temp = possibleCards[i].number;
                            possibleCards[i].number = possibleCards[j].number;
                            possibleCards[j].number = temp;
                        }
                    }
                }


                if (r.cardStack[0].number > r.cardStack[1].number)
                    stackmaxnumber = r.cardStack[0].number;
                else
                    stackmaxnumber = r.cardStack[1].number;

                for (int i = 2; i < 4; i++)
                {
                    if (r.cardStack[i] != null && r.cardStack[i].number > stackmaxnumber)
                    {
                        stackmaxnumber = r.cardStack[i].number;
                    }
                }
                for (int j = 0; j < possibleCards.Count; j++)
                {
                    if (stackmaxnumber < possibleCards[j].number)
                        return possibleCards[j];
                }
                return (HandedCard)possibleCards[0];
            }





            if (gameInfo.roundCardIdx == 0)
            {
                if (gameInfo.myInfo == gameInfo.attackPlayer)
                {
                    for (int i = 0; i < possibleCards.Count; i++)
                    {
                        if (((HandedCard)possibleCards[i]).shape == (Shape)gameInfo.betting.giruda)
                            return (HandedCard)possibleCards[i];
                    }
                    return (HandedCard)possibleCards[0];
                }
                return (HandedCard)possibleCards[10 - gameInfo.roundIdx];
            }




            else
            {
                if (r.cardStack[0].shape == Shape.Joker || r.cardStack[1].shape == Shape.Joker)
                    return (HandedCard)possibleCards[0];

                Random rndCard = new Random();
                int k = rndCard.Next(possibleCards.Count);

                return (HandedCard)possibleCards[k];
            }


        }

    }
}
